#ifndef _COMM_HPP_
#define _COMM_HPP_

#include<iostream>
#include<cstdio>
#include<cerrno>
#include<cstring>
#include<cstdlib>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#define PATHNAME "."
#define PROJ_ID 0x66
#define MAX_SIZE 4096
//共享内存的大小，建议是4KB的整数倍
//系统分配共享内存是以4KB为单位的 --- 内存划分内存块的基本单位 Page
//如果不是倍数，内核会给你向上取整，内核给你的，和你能用的，是两码事

key_t getKey()
{
    key_t k=ftok(PATHNAME,PROJ_ID);//可以获得同样的key
    if(k<0)
    {
        std::cerr<<errno<<":"<<strerror(errno)<<std::endl;
        exit(1);
    }
    return k;
}
int getShmHelpter(key_t k,int flags)
{
    //k是要shmget，设置进入共享内存属性中的
    //用来表示该共享内存，在内核中的唯一性
    //shmid vs key
    //fd    vs inode
  int shmid=shmget(k,MAX_SIZE,flags);
  if(shmid<0)
  {
    std::cerr<<errno<<":"<<strerror(errno)<<std::endl;
    exit(2);
  }
  return shmid;
}
int getShm(key_t k)
{
    return getShmHelpter(k,IPC_CREAT);
}
int creatShm(key_t k)
{
   return getShmHelpter(k,IPC_CREAT|IPC_EXCL|0600);
}
void *attachShm(int shmid)//将共享内存和进程地址空间联系
{
    void* mem=shmat(shmid,nullptr,0);//linux64位系统指针8个字节,用Int会失真
    if((long long)mem==-1L)
    {
        std::cerr<<errno<<":"<<strerror(errno)<<std::endl;
        exit(3);
    }
    return mem;
}
void detachShm(void* start)
{
    if(shmdt(start)==-1)
    {
        std::cerr<<"shmdt:"<<errno<<":"<<strerror(errno)<<std::endl;
    }
}
void delShm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,nullptr)==-1)
    {
        std::cerr<<errno<<":"<<strerror(errno)<<std::endl;
    }
}
#endif